import random
from flask import Flask, current_app, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from rediscluster import StrictRedisCluster
from werkzeug.routing import BaseConverter
from Day07.d01_pyjwt import generate_jwt, verify_jwt
from datetime import datetime, timedelta

app = Flask(__name__)
# 配置信息
class Config(object):
    # 配置链接mysql
    SQLALCHEMY_DATABASE_URI = 'mysql://root:mysql@127.0.0.1:3306/toutiao'
    # 设置不追踪修改
    SQLALCHMEY_TRACK_MODIFICATIONS = True
    SQLALCHEMY_ECHO = False

    # 集群节点
    REDIS_CLUSTER = [
        {'host': '127.0.0.1', 'port': '7000'},
        {'host': '127.0.0.1', 'port': '7001'},
        {'host': '127.0.0.1', 'port': '7002'},
    ]

    # jwt 秘钥
    JWT_SECRET_KEY = 'abcdefg'
# 自定义转换器
class Mobile(BaseConverter):
    regex = r'1[3-9]\d{9}'

# 把自定义的转换器添加到系统转换器字典中
app.url_map.converters['mobile'] = Mobile
# 从配置类中加载配置信息
app.config.from_object(Config)
# 创建redis集群对象,并添加到app属性中,方便在视图使用
app.redis_cluster = StrictRedisCluster(startup_nodes=app.config['REDIS_CLUSTER'])

# 创建sqlalchemy对象,并关联app
db = SQLAlchemy(app)
# 定义用户表的模型类
class User(db.Model):
    """
    用户基本信息
    """
    __tablename__ = 'user_basic'

    class STATUS:
        ENABLE = 1
        DISABLE = 0

    id = db.Column('user_id', db.Integer, primary_key=True, doc='用户ID')
    mobile = db.Column(db.String, doc='手机号')
    password = db.Column(db.String, doc='密码')
    name = db.Column('user_name', db.String, doc='昵称')
    profile_photo = db.Column(db.String, doc='头像')
    last_login = db.Column(db.DateTime, doc='最后登录时间')
    is_media = db.Column(db.Boolean, default=False, doc='是否是自媒体')
    is_verified = db.Column(db.Boolean, default=False, doc='是否实名认证')
    introduction = db.Column(db.String, doc='简介')
    certificate = db.Column(db.String, doc='认证')
    article_count = db.Column(db.Integer, default=0, doc='发帖数')
    following_count = db.Column(db.Integer, default=0, doc='关注的人数')
    fans_count = db.Column(db.Integer, default=0, doc='被关注的人数（粉丝数）')
    like_count = db.Column(db.Integer, default=0, doc='累计点赞人数')
    read_count = db.Column(db.Integer, default=0, doc='累计阅读人数')

    account = db.Column(db.String, doc='账号')
    email = db.Column(db.String, doc='邮箱')
    status = db.Column(db.Integer, default=1, doc='状态，是否可用')

@app.route('/')
def index():
    data = {}
    for rule in app.url_map.iter_rules():
        data[rule.endpoint] = rule.rule
    return jsonify(data)

@app.route('/sms/<mobile:mobile>')
def send_code(mobile):
    # 发送验证码
    # 生成验证,6位验证码
    code = str(random.randint(100000, 999999))
    # 假设发送成功,保存到redis中
    current_app.redis_cluster.set(mobile, code)
    return code

@app.route('/login')
def login():
    """
    登录接口
    :return:
    """
    # 获取参数
    mobile = request.args.get('mobile')
    code = request.args.get('code')

    # 为空检验
    redis_code = app.redis_cluster.get(mobile)
    if not code or code != redis_code.decode():
        return '验证码错误'
    user = User.query.filter_by(mobile=mobile).first()
    if user is None:
        #如果不存在,创建用户
        user = User(mobile=mobile, name=mobile)
        db.session.add(user)
        db.session.commit()
    else:
        # 一般还要判断是否可用
        pass
    # 生成jwt token
    payload = {
        'user_id': user.id
    }
    expiry = datetime.utcnow()+timedelta(hours=2)
    token = generate_jwt(payload, expiry, current_app.config['JWT_SECRET_KEY'])
    return token

@app.route('/userinfo')
def userinfo():
    # 从请求头中获取token
    token = request.headers.get('Authorization')
    if not token:
        return '没有token,请先登录'
    # 检验token,返回payload
    payload = verify_jwt(token, current_app.config['JWT_SECRET_KEY'])
    if payload is None:
        return 'token已过期,请重新登录'
    user = User.query.get(payload.get('user_id'))
    return '你好! {}'.format(user.name)

if __name__ == '__main__':
    app.run(host='192.168.226.129', debug=True)


